
package com.jf.cloud.common.security.filter;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import com.jf.cloud.common.handler.HttpHandler;
import com.jf.cloud.common.handler.SensitiveHandler;
import com.jf.cloud.common.response.ResponseEnum;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.security.config.SensitiveWordConfig;
import com.jf.cloud.common.security.wrapper.RequestWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.Set;

/**
 * @author zz
 */
@Component
public class SensitiveFilter implements Filter {
    private static final Logger logger = LoggerFactory.getLogger(SensitiveFilter.class);

    @Autowired
    private HttpHandler httpHandler;
    @Autowired
    private SensitiveHandler sensitiveHandler;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        ServletRequestAttributes attributes = new ServletRequestAttributes(req, resp);
        RequestContextHolder.setRequestAttributes(attributes);
        logger.info("AuthFilter RequestURI :{}", req.getRequestURI().replaceAll("[\r\n]", ""));
        Set<String> sensitiveWhiteSet = SensitiveWordConfig.getSensitiveWhiteSet();
        AntPathMatcher antPathMatcher = new AntPathMatcher();
        if (CollectionUtil.isNotEmpty(sensitiveWhiteSet)) {
            for (String sensitiveUrl : sensitiveWhiteSet) {
                if (antPathMatcher.match(sensitiveUrl, req.getRequestURI())) {
                    chain.doFilter(req, resp);
                    return;
                }
            }
        }
        // 敏感词输入过滤
        if (StrUtil.isNotBlank(req.getContentType()) && req.getContentType().contains(ContentType.JSON.getValue())) {
            RequestWrapper requestWrapper;
            requestWrapper = new RequestWrapper(req);
            String body = requestWrapper.getBody();
            if (StrUtil.isNotBlank(body) && sensitiveHandler.isSensitive(body)) {
                httpHandler.printServerResponseToWeb(ServerResponseEntity.fail(ResponseEnum.SENSITIVE_WORD));
                return;
            }
            //xss
            chain.doFilter(requestWrapper, resp);
        } else {
            Map<String, String[]> parameterMap = req.getParameterMap();
            StringBuilder stringBuilder = new StringBuilder();
            for (String s : parameterMap.keySet()) {
                stringBuilder.append(parameterMap.get(s)[0]);
            }
            // 传入参数是否包含敏感词,最小匹配
            if (StrUtil.isNotBlank(stringBuilder.toString()) && sensitiveHandler.isSensitive(stringBuilder.toString())) {
                httpHandler.printServerResponseToWeb(ServerResponseEntity.fail(ResponseEnum.SENSITIVE_WORD));
                return;
            }
            chain.doFilter(req, resp);
        }
    }
}
